﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Device.Location;
using System.ComponentModel;

using Microsoft.Phone.Controls;
using Microsoft.Phone.Controls.Maps;
using Microsoft.Phone.Controls.Maps.Platform;


namespace WP7SignalRHelperClient
{
    public partial class Map : PhoneApplicationPage
    {
        #region Private Members"
                
        private GeoCoordinateWatcher gcw;

        BackgroundWorker MapBackgroundDataWorker = new BackgroundWorker();
        
        #endregion        

        #region "Constructor"

        public Map()
        {
            InitializeComponent();

            // Set up the background workers.
            MapBackgroundDataWorker.WorkerSupportsCancellation = false;
            MapBackgroundDataWorker.WorkerReportsProgress = false;
            MapBackgroundDataWorker.DoWork += new DoWorkEventHandler(MapBackgroundDataWorker_DoWork);
        }

        #endregion

        #region "Eveny Handlers"

        private void gcw_StatusChanged(object sender, GeoPositionStatusChangedEventArgs e)
        {
            if (e.Status == GeoPositionStatus.Ready)
            {
                // Get position from watcher & stop it to conserve battery.
                double phoneLatitude = gcw.Position.Location.Latitude;
                double phoneLongitude = gcw.Position.Location.Longitude;
                gcw.Stop();

                // Map it on phone.
                this.AddPushPin(phoneLatitude, phoneLongitude);

                MapClient phoneToMap = new MapClient();
                phoneToMap.PhoneClientId = App.Current.DeviceID;
                phoneToMap.Latitude = phoneLatitude;
                phoneToMap.Longitude = phoneLongitude;

                // Send to server for mapping.
                App.Current.SignalRHub.MapIt(phoneToMap);
            }
            else if (e.Status == GeoPositionStatus.NoData || e.Status == GeoPositionStatus.Disabled)
            {
                MessageBox.Show("Unable to determine current geo-location.", "Location Error", MessageBoxButton.OK);
                gcw.Stop();
            }
        }

        private void shareLocationLink_Click(object sender, RoutedEventArgs e)
        {
            if (gcw == null)
            {
                // Look for present geo-location of phone .. with user persimission please.
                gcw = new GeoCoordinateWatcher(GeoPositionAccuracy.High);
                gcw.MovementThreshold = 10;
                gcw.StatusChanged += new EventHandler<GeoPositionStatusChangedEventArgs>(gcw_StatusChanged);
            }

            gcw.Start();          
        }

        protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
        {
            base.OnNavigatedTo(e);

            // Instantiate with default or any other implementation.
            App.Current.SignalRHub = new SignalRMessagingHub();
        }

        protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)
        {
            base.OnNavigatedFrom(e);

            // Fire off background thread to unmap oneself from Server map.               
            MapBackgroundDataWorker.RunWorkerAsync();     
        }

        private void MapBackgroundDataWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            MapClient phoneToUnMap = new MapClient();
            phoneToUnMap.PhoneClientId = App.Current.DeviceID;
            phoneToUnMap.Latitude = 0;
            phoneToUnMap.Longitude = 0;

            // Send to server for un-mapping.
            App.Current.SignalRHub.UnMapIt(phoneToUnMap);
        }

        private void AddPushPin(double lat, double lon)
        {
            // Drop Pushpin at desired location.
            Location desiredLocation = new Location();
            desiredLocation.Latitude = lat;
            desiredLocation.Longitude = lon;

            // Add whatever Pushpin characteristics desired.
            Pushpin pushpin = new Pushpin();
            pushpin.Location = desiredLocation;
            pushpin.Background = new SolidColorBrush(Colors.Red);
            this.locationMap.Children.Add(pushpin);
        }

        #endregion       
    }
}